/*
 * commons is a based project implemented
 * Copyright (C) 2024 Jasmine
 */
package com.easy.redis.lock;/*
                               * 文件名：RedisDistributedLock.java
                               * 版权：Copyright by www.ahqianmo.com
                               * 描述：
                               * 修改人： Jasmine
                               * 修改时间：2021年07月29日
                               * 跟踪单号：
                               * 修改单号：
                               * 修改内容：
                               */

/*

package com.cloud.commons.redis.lock;

import org.redisson.RedissonMultiLock;
import org.redisson.RedissonRedLock;
import org.redisson.api.RCountDownLatch;
import org.redisson.api.RLock;
import org.redisson.api.RPermitExpirableSemaphore;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

*/
/**
 * https://github.com/redisson/redisson/wiki/8.-%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81%E5%92%8C%E5%90%8C%E6%AD%A5%E5%99%A8
 *
 * @author Jasmine
 * @version 1.0
 * @date 2021-07-29 17:13:13
 * @see RedissonDistributedLock
 * @since JDK1.8
 *        <p>
 *        1. 可重入锁（Reentrant Lock） Redisson的分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口，同时还支持自动过期解锁。
 *        RLock对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁，其他进程解锁则会抛出IllegalMonitorStateException
 *        错误。但是如果遇到需要其他进程也能解锁的情况，请使用分布式信号量Semaphore 对象.
 *        <p>
 *        2. 公平锁（Fair Lock）
 *        Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        它保证了当多个Redisson客户端线程同时请求加锁时，优先分配给先发出请求的线程。所有请求线程会在一个队列中排队，当某个线程出现宕机时，Redisson会等待5秒后继续下一个线程，也就是说如果前面有5
 *        个线程都处于等待状态，那么后面的线程会等待至少25秒。
 *        <p>
 *        3. 联锁（MultiLock） Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *        <p>
 *        4. 红锁（RedLock）
 *        Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *        <p>
 *        5. 读写锁（ReadWriteLock） Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks
 *        .ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。
 *        <p>
 *        6. 信号量（Semaphore） Redisson的分布式信号量（Semaphore）Java对象RSemaphore采用了与java.util.concurrent
 *        .Semaphore相似的接口和用法。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        <p>
 *        7. 可过期性信号量（PermitExpirableSemaphore）
 *        Redisson可过期性信号量（PermitExpirableSemaphore）是在RSemaphore对象的基础上，为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识，释放时只能通过提交这个ID
 *        才能释放。它提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        <p>
 *        8. 闭锁（CountDownLatch）
 *        Redisson分布式闭锁（CountDownLatch）Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。
 *        <p>
 *        1. 可重入锁（Reentrant Lock） Redisson的分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口，同时还支持自动过期解锁。
 *        RLock对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁，其他进程解锁则会抛出IllegalMonitorStateException
 *        错误。但是如果遇到需要其他进程也能解锁的情况，请使用分布式信号量Semaphore 对象.
 *        <p>
 *        2. 公平锁（Fair Lock）
 *        Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        它保证了当多个Redisson客户端线程同时请求加锁时，优先分配给先发出请求的线程。所有请求线程会在一个队列中排队，当某个线程出现宕机时，Redisson会等待5秒后继续下一个线程，也就是说如果前面有5
 *        个线程都处于等待状态，那么后面的线程会等待至少25秒。
 *        <p>
 *        3. 联锁（MultiLock） Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *        <p>
 *        4. 红锁（RedLock）
 *        Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *        <p>
 *        5. 读写锁（ReadWriteLock） Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks
 *        .ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。
 *        <p>
 *        6. 信号量（Semaphore） Redisson的分布式信号量（Semaphore）Java对象RSemaphore采用了与java.util.concurrent
 *        .Semaphore相似的接口和用法。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        <p>
 *        7. 可过期性信号量（PermitExpirableSemaphore）
 *        Redisson可过期性信号量（PermitExpirableSemaphore）是在RSemaphore对象的基础上，为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识，释放时只能通过提交这个ID
 *        才能释放。它提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *        <p>
 *        8. 闭锁（CountDownLatch）
 *        Redisson分布式闭锁（CountDownLatch）Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。
 *//*
   
   //@ConditionalOnClass(RedissonClient.class)
   public class RedissonDistributedLock {
   
    @Autowired
    private RedissonClient redisson;
   
    */
/**
 * 1. 可重入锁（Reentrant Lock） Redisson的分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口，同时还支持自动过期解锁。
 * RLock对象完全符合Java的Lock规范。也就是说只有拥有锁的进程才能解锁，其他进程解锁则会抛出IllegalMonitorStateException
 * 错误。但是如果遇到需要其他进程也能解锁的情况，请使用分布式信号量Semaphore 对象.
 *//*
   
    public void testReentrantLock() {
        RLock lock = redisson.getLock("anyLock");
        try {
            // 1. 最常见的使用方法
            //lock.lock();
   
            // 2. 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁
            //lock.lock(10, TimeUnit.SECONDS);
   
            // 3. 尝试加锁，最多等待3秒，上锁以后10秒自动解锁
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (res) {    //成功
                // do your business
   
            }
   
            //4. Redisson同时还为分布式锁提供了异步执行的相关方法：
            lock.lockAsync();
            lock.lockAsync(10, TimeUnit.SECONDS);
            Future<Boolean> fu = lock.tryLockAsync(100, 10, TimeUnit.SECONDS);
   
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
   
    }
   
   
    */
/**
 * 2. 公平锁（Fair Lock）
 * Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 * 它保证了当多个Redisson客户端线程同时请求加锁时，优先分配给先发出请求的线程。所有请求线程会在一个队列中排队，当某个线程出现宕机时，Redisson会等待5秒后继续下一个线程，也就是说如果前面有5
 * 个线程都处于等待状态，那么后面的线程会等待至少25秒。
 *//*
   
    public void testFairLock(RedissonClient redisson) {
   
        RLock fairLock = redisson.getFairLock("anyLock");
        try {
            // 最常见的使用方法
            fairLock.lock();
   
            // 支持过期解锁功能, 10秒钟以后自动解锁,无需调用unlock方法手动解锁
            fairLock.lock(10, TimeUnit.SECONDS);
   
            // 尝试加锁，最多等待100秒，上锁以后10秒自动解锁
            boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
   
            //Redisson同时还为分布式可重入公平锁提供了异步执行的相关方法：
            fairLock.lockAsync();
            fairLock.lockAsync(10, TimeUnit.SECONDS);
            Future<Boolean> f = fairLock.tryLockAsync(100, 10, TimeUnit.SECONDS);
   
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            fairLock.unlock();
        }
    }
   
    */
/**
 * 3. 联锁（MultiLock） Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *//*
   
    public void testMultiLock(RedissonClient redisson1,
                              RedissonClient redisson2, RedissonClient redisson3) {
   
        RLock lock1 = redisson1.getLock("lock1");
        RLock lock2 = redisson2.getLock("lock2");
        RLock lock3 = redisson3.getLock("lock3");
   
        RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
   
        try {
            // 同时加锁：lock1 lock2 lock3, 所有的锁都上锁成功才算成功。
            lock.lock();
   
            // 尝试加锁，最多等待100秒，并在加锁成功10秒钟后自动解开
            boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
   
            // 给lock1，lock2，lock3加锁，如果没有手动解开的话，10秒钟后将会自动解开
            lock.lock(10, TimeUnit.SECONDS);
   
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
   
    }
   
    */
/**
 * 4. 红锁（RedLock） Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁，每个RLock对象实例可以来自于不同的Redisson实例。
 *//*
   
   
    public void testRedLock(RedissonClient redisson1,
                            RedissonClient redisson2, RedissonClient redisson3) {
   
        RLock lock1 = redisson1.getLock("lock1");
        RLock lock2 = redisson2.getLock("lock2");
        RLock lock3 = redisson3.getLock("lock3");
   
        RedissonRedLock lock = new RedissonRedLock(lock1, lock2, lock3);
        try {
            // 同时加锁：lock1 lock2 lock3, 红锁在大部分节点上加锁成功就算成功。
            lock.lock();
   
            // 尝试加锁，最多等待100秒，上锁以后10秒自动解锁
            boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
   
            // 给lock1，lock2，lock3加锁，如果没有手动解开的话，10秒钟后将会自动解开
            lock.lock(10, TimeUnit.SECONDS);
   
            // 为加锁等待100秒时间，并在加锁成功10秒钟后自动解开
            res = lock.tryLock(100, 10, TimeUnit.SECONDS);
            lock.unlock();
   
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
   
    }
   
    */
/**
 * 5. 读写锁（ReadWriteLock） Redisson分布式可重入读写锁RReadWriteLock Java对象实现了java.util.concurrent.locks
 * .ReadWriteLock接口。其中读锁和写锁都继承了RLock接口。分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。
 *//*
   
    public void readWrite() throws InterruptedException {
        RReadWriteLock rwlock = redisson.getReadWriteLock("anyRWLock");
        // 最常见的使用方法
        rwlock.readLock().lock();
        // 或
        rwlock.writeLock().lock();
   
        //支持过期解锁功能  10秒钟以后自动解锁,无需调用unlock方法手动解锁
        rwlock.readLock().lock(10, TimeUnit.SECONDS);
        // 或
        rwlock.writeLock().lock(10, TimeUnit.SECONDS);
   
        // 尝试加锁，最多等待100秒，上锁以后10秒自动解锁
        boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
        // 或
        res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
        rwlock.readLock().unlock();
        rwlock.writeLock().unlock();
    }
   
   
    */
/**
 * 6. 信号量（Semaphore） Redisson的分布式信号量（Semaphore）Java对象RSemaphore采用了与java.util.concurrent
 * .Semaphore相似的接口和用法。同时还提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *//*
   
    public void sempa() throws InterruptedException {
        RSemaphore semaphore = redisson.getSemaphore("semaphore");
        semaphore.acquire();
        //或
        semaphore.acquireAsync();
        semaphore.acquire(23);
        semaphore.tryAcquire();
        //或
        semaphore.tryAcquireAsync();
        semaphore.tryAcquire(23, TimeUnit.SECONDS);
        //或
        semaphore.tryAcquireAsync(23, TimeUnit.SECONDS);
        semaphore.release(10);
        semaphore.release();
        //或
        semaphore.releaseAsync();
    }
   
    */
/**
 * 7. 可过期性信号量（PermitExpirableSemaphore）
 * Redisson可过期性信号量（PermitExpirableSemaphore）是在RSemaphore对象的基础上，为每个信号增加了一个过期时间。每个信号可以通过独立的ID来辨识，释放时只能通过提交这个ID
 * 才能释放。它提供了异步（Async）、反射式（Reactive）和RxJava2标准的接口。
 *//*
   
    public void tes() throws InterruptedException {
        RPermitExpirableSemaphore semaphore = redisson.getPermitExpirableSemaphore("mySemaphore");
        String permitId = semaphore.acquire();
        // 获取一个信号，有效期只有2秒钟。
        permitId = semaphore.acquire(2, TimeUnit.SECONDS);
        // ...
        semaphore.release(permitId);
    }
   
    */
/**
 * 8. 闭锁（CountDownLatch）
 * Redisson分布式闭锁（CountDownLatch）Java对象RCountDownLatch采用了与java.util.concurrent.CountDownLatch相似的接口和用法。
 *//*
   
    public void tt() throws InterruptedException {
        RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
        latch.trySetCount(1);
        latch.await();
   
        // 在其他线程或其他JVM里
        latch = redisson.getCountDownLatch("anyCountDownLatch");
        latch.countDown();
    }
   }*/
